<template>
  <div class="w-full">
    <el-input
      ref="inputRef"
      v-model="inputIconValue"
      :clearable="clearable"
      placeholder="点击选择图标"
      @click="visible = !visible"
      @clear="clearIcon"
      @keydown.prevent
      @focus="(e: FocusEvent) => (e.target as HTMLInputElement).blur()"
    >
      <template #append>
        <SvgIcon v-if="props.iconType == 'svg'" :size="'1.6rem'" :name="inputIconValue" />
        <el-icon v-else size="25" class="mx-1">
          <component :is="elIcons[inputIconValue]"></component>
        </el-icon>
      </template>
    </el-input>
    <el-dialog v-model="visible" center title="选择图标" width="70%">
      <div>
        <el-input v-model="filterValue" placeholder="输入图标名称" clearable @input="filterIcon" />
        <el-divider border-style="dashed" />
        <el-scrollbar height="300px">
          <div class="icon-list">
            <div v-for="iconName in filterIconList" :key="iconName" class="icon-item" @click="handleSelect(iconName)">
              <SvgIcon v-if="props.iconType == 'svg'" :name="iconName" size="2rem" />
              <el-icon v-else size="25">
                <component :is="iconName"></component>
              </el-icon>
              <span class="single-line-ellipsis">{{ iconName }}</span>
            </div>
          </div>
        </el-scrollbar>
      </div>
    </el-dialog>
  </div>
</template>
<script setup lang="ts" name="SelectIcon">
import * as elIcons from "@element-plus/icons-vue";

const emit = defineEmits(["update:modelValue"]);
const props = defineProps({
  modelValue: {
    type: String,
    require: false,
    default: ""
  },
  iconType: {
    type: String,
    require: false,
    default: "element-plus"
  },
  readonly: {
    type: Boolean,
    require: false,
    default: true
  },
  clearable: {
    type: Boolean,
    require: false,
    default: false
  }
});

// 重新接收，防止打包后 clearable 报错
const inputIconValue = ref(props.modelValue);

const visible = ref(false); // 弹窗显示状态
const allIconList = ref([]); // 所有的图标集合
const filterIconList = ref([]); // 筛选后图标集合
const filterValue = ref(""); // 筛选关键词

onMounted(() => {
  loadAllIcons();
});

// 获取所有图标
const loadAllIcons = () => {
  if (props.iconType === "svg") {
    const icons = import.meta.glob("@/assets/svg/*.svg");
    for (const key in icons) {
      const iconName = key.split("/src/assets/svg/")[1].split(".")[0];
      allIconList.value.push(iconName);
    }
  } else {
    allIconList.value = Object.keys(elIcons);
  }
  filterIconList.value = [...allIconList.value];
};

// 筛选 icon
const filterIcon = () => {
  if (!filterValue.value) return (filterIconList.value = [...allIconList.value]);
  filterIconList.value = allIconList.value.filter(iconName =>
    props.iconType === "svg" ? iconName.includes(filterValue.value) : iconName.toLowerCase().includes(filterValue.value)
  );
};

// 选中 icon
const handleSelect = iconName => {
  emit("update:modelValue", iconName);
  inputIconValue.value = iconName;
  visible.value = false;
  filterValue.value = "";
  filterIconList.value = [...allIconList.value];
};

const inputRef = ref();
const clearIcon = () => {
  inputIconValue.value = "";
  emit("update:modelValue", "");
};
</script>
<style lang="scss" scoped>
.el-divider--horizontal {
  margin: 10px auto !important;
}
.icon-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, 120px);
  gap: 20px;
  justify-content: space-evenly;
  .icon-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    &:hover {
      color: var(--el-color-primary);
      transform: scale(1.2);
      transition: all 0.2s;
    }
  }
}
:deep(.el-input-group__append) {
  padding: 4px;
}
</style>
